<!DOCTYPE html><html><head>
      <title>front-end-interview-case</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      
      <link rel="stylesheet" href="file:///c:\Users\LiuyangWang\.vscode\extensions\shd101wyy.markdown-preview-enhanced-0.8.7\crossnote\dependencies\katex\katex.min.css">
      
      
      
      
      
      <style>
      code[class*=language-],pre[class*=language-]{color:#333;background:0 0;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.4;-moz-tab-size:8;-o-tab-size:8;tab-size:8;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:.8em;overflow:auto;border-radius:3px;background:#f5f5f5}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal;background:#f5f5f5}.token.blockquote,.token.comment{color:#969896}.token.cdata{color:#183691}.token.doctype,.token.macro.property,.token.punctuation,.token.variable{color:#333}.token.builtin,.token.important,.token.keyword,.token.operator,.token.rule{color:#a71d5d}.token.attr-value,.token.regex,.token.string,.token.url{color:#183691}.token.atrule,.token.boolean,.token.code,.token.command,.token.constant,.token.entity,.token.number,.token.property,.token.symbol{color:#0086b3}.token.prolog,.token.selector,.token.tag{color:#63a35c}.token.attr-name,.token.class,.token.class-name,.token.function,.token.id,.token.namespace,.token.pseudo-class,.token.pseudo-element,.token.url-reference .token.variable{color:#795da3}.token.entity{cursor:help}.token.title,.token.title .token.punctuation{font-weight:700;color:#1d3e81}.token.list{color:#ed6a43}.token.inserted{background-color:#eaffea;color:#55a532}.token.deleted{background-color:#ffecec;color:#bd2c00}.token.bold{font-weight:700}.token.italic{font-style:italic}.language-json .token.property{color:#183691}.language-markup .token.tag .token.punctuation{color:#333}.language-css .token.function,code.language-css{color:#0086b3}.language-yaml .token.atrule{color:#63a35c}code.language-yaml{color:#183691}.language-ruby .token.function{color:#333}.language-markdown .token.url{color:#795da3}.language-makefile .token.symbol{color:#795da3}.language-makefile .token.variable{color:#183691}.language-makefile .token.builtin{color:#0086b3}.language-bash .token.keyword{color:#0086b3}pre[data-line]{position:relative;padding:1em 0 1em 3em}pre[data-line] .line-highlight-wrapper{position:absolute;top:0;left:0;background-color:transparent;display:block;width:100%}pre[data-line] .line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:hsla(24,20%,50%,.08);background:linear-gradient(to right,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));pointer-events:none;line-height:inherit;white-space:pre}pre[data-line] .line-highlight:before,pre[data-line] .line-highlight[data-end]:after{content:attr(data-start);position:absolute;top:.4em;left:.6em;min-width:1em;padding:0 .5em;background-color:hsla(24,20%,50%,.4);color:#f4f1ef;font:bold 65%/1.5 sans-serif;text-align:center;vertical-align:.3em;border-radius:999px;text-shadow:none;box-shadow:0 1px #fff}pre[data-line] .line-highlight[data-end]:after{content:attr(data-end);top:auto;bottom:.4em}html body{font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif;font-size:16px;line-height:1.6;color:#333;background-color:#fff;overflow:initial;box-sizing:border-box;word-wrap:break-word}html body>:first-child{margin-top:0}html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{line-height:1.2;margin-top:1em;margin-bottom:16px;color:#000}html body h1{font-size:2.25em;font-weight:300;padding-bottom:.3em}html body h2{font-size:1.75em;font-weight:400;padding-bottom:.3em}html body h3{font-size:1.5em;font-weight:500}html body h4{font-size:1.25em;font-weight:600}html body h5{font-size:1.1em;font-weight:600}html body h6{font-size:1em;font-weight:600}html body h1,html body h2,html body h3,html body h4,html body h5{font-weight:600}html body h5{font-size:1em}html body h6{color:#5c5c5c}html body strong{color:#000}html body del{color:#5c5c5c}html body a:not([href]){color:inherit;text-decoration:none}html body a{color:#08c;text-decoration:none}html body a:hover{color:#00a3f5;text-decoration:none}html body img{max-width:100%}html body>p{margin-top:0;margin-bottom:16px;word-wrap:break-word}html body>ol,html body>ul{margin-bottom:16px}html body ol,html body ul{padding-left:2em}html body ol.no-list,html body ul.no-list{padding:0;list-style-type:none}html body ol ol,html body ol ul,html body ul ol,html body ul ul{margin-top:0;margin-bottom:0}html body li{margin-bottom:0}html body li.task-list-item{list-style:none}html body li>p{margin-top:0;margin-bottom:0}html body .task-list-item-checkbox{margin:0 .2em .25em -1.8em;vertical-align:middle}html body .task-list-item-checkbox:hover{cursor:pointer}html body blockquote{margin:16px 0;font-size:inherit;padding:0 15px;color:#5c5c5c;background-color:#f0f0f0;border-left:4px solid #d6d6d6}html body blockquote>:first-child{margin-top:0}html body blockquote>:last-child{margin-bottom:0}html body hr{height:4px;margin:32px 0;background-color:#d6d6d6;border:0 none}html body table{margin:10px 0 15px 0;border-collapse:collapse;border-spacing:0;display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}html body table th{font-weight:700;color:#000}html body table td,html body table th{border:1px solid #d6d6d6;padding:6px 13px}html body dl{padding:0}html body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}html body dl dd{padding:0 16px;margin-bottom:16px}html body code{font-family:Menlo,Monaco,Consolas,'Courier New',monospace;font-size:.85em;color:#000;background-color:#f0f0f0;border-radius:3px;padding:.2em 0}html body code::after,html body code::before{letter-spacing:-.2em;content:'\00a0'}html body pre>code{padding:0;margin:0;word-break:normal;white-space:pre;background:0 0;border:0}html body .highlight{margin-bottom:16px}html body .highlight pre,html body pre{padding:1em;overflow:auto;line-height:1.45;border:#d6d6d6;border-radius:3px}html body .highlight pre{margin-bottom:0;word-break:normal}html body pre code,html body pre tt{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}html body pre code:after,html body pre code:before,html body pre tt:after,html body pre tt:before{content:normal}html body blockquote,html body dl,html body ol,html body p,html body pre,html body ul{margin-top:0;margin-bottom:16px}html body kbd{color:#000;border:1px solid #d6d6d6;border-bottom:2px solid #c7c7c7;padding:2px 4px;background-color:#f0f0f0;border-radius:3px}@media print{html body{background-color:#fff}html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{color:#000;page-break-after:avoid}html body blockquote{color:#5c5c5c}html body pre{page-break-inside:avoid}html body table{display:table}html body img{display:block;max-width:100%;max-height:100%}html body code,html body pre{word-wrap:break-word;white-space:pre}}.markdown-preview{width:100%;height:100%;box-sizing:border-box}.markdown-preview ul{list-style:disc}.markdown-preview ul ul{list-style:circle}.markdown-preview ul ul ul{list-style:square}.markdown-preview ol{list-style:decimal}.markdown-preview ol ol,.markdown-preview ul ol{list-style-type:lower-roman}.markdown-preview ol ol ol,.markdown-preview ol ul ol,.markdown-preview ul ol ol,.markdown-preview ul ul ol{list-style-type:lower-alpha}.markdown-preview .newpage,.markdown-preview .pagebreak{page-break-before:always}.markdown-preview pre.line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}.markdown-preview pre.line-numbers>code{position:relative}.markdown-preview pre.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:1em;font-size:100%;left:0;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-preview pre.line-numbers .line-numbers-rows>span{pointer-events:none;display:block;counter-increment:linenumber}.markdown-preview pre.line-numbers .line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}.markdown-preview .mathjax-exps .MathJax_Display{text-align:center!important}.markdown-preview:not([data-for=preview]) .code-chunk .code-chunk-btn-group{display:none}.markdown-preview:not([data-for=preview]) .code-chunk .status{display:none}.markdown-preview:not([data-for=preview]) .code-chunk .output-div{margin-bottom:16px}.markdown-preview .md-toc{padding:0}.markdown-preview .md-toc .md-toc-link-wrapper .md-toc-link{display:inline;padding:.25rem 0}.markdown-preview .md-toc .md-toc-link-wrapper .md-toc-link div,.markdown-preview .md-toc .md-toc-link-wrapper .md-toc-link p{display:inline}.markdown-preview .md-toc .md-toc-link-wrapper.highlighted .md-toc-link{font-weight:800}.scrollbar-style::-webkit-scrollbar{width:8px}.scrollbar-style::-webkit-scrollbar-track{border-radius:10px;background-color:transparent}.scrollbar-style::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(150,150,150,.66);border:4px solid rgba(150,150,150,.66);background-clip:content-box}html body[for=html-export]:not([data-presentation-mode]){position:relative;width:100%;height:100%;top:0;left:0;margin:0;padding:0;overflow:auto}html body[for=html-export]:not([data-presentation-mode]) .markdown-preview{position:relative;top:0;min-height:100vh}@media screen and (min-width:914px){html body[for=html-export]:not([data-presentation-mode]) .markdown-preview{padding:2em calc(50% - 457px + 2em)}}@media screen and (max-width:914px){html body[for=html-export]:not([data-presentation-mode]) .markdown-preview{padding:2em}}@media screen and (max-width:450px){html body[for=html-export]:not([data-presentation-mode]) .markdown-preview{font-size:14px!important;padding:1em}}@media print{html body[for=html-export]:not([data-presentation-mode]) #sidebar-toc-btn{display:none}}html body[for=html-export]:not([data-presentation-mode]) #sidebar-toc-btn{position:fixed;bottom:8px;left:8px;font-size:28px;cursor:pointer;color:inherit;z-index:99;width:32px;text-align:center;opacity:.4}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] #sidebar-toc-btn{opacity:1}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc{position:fixed;top:0;left:0;width:300px;height:100%;padding:32px 0 48px 0;font-size:14px;box-shadow:0 0 4px rgba(150,150,150,.33);box-sizing:border-box;overflow:auto;background-color:inherit}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar{width:8px}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-track{border-radius:10px;background-color:transparent}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(150,150,150,.66);border:4px solid rgba(150,150,150,.66);background-clip:content-box}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc a{text-decoration:none}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc{padding:0 16px}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc .md-toc-link-wrapper .md-toc-link{display:inline;padding:.25rem 0}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc .md-toc-link-wrapper .md-toc-link div,html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc .md-toc-link-wrapper .md-toc-link p{display:inline}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc .md-toc-link-wrapper.highlighted .md-toc-link{font-weight:800}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{left:300px;width:calc(100% - 300px);padding:2em calc(50% - 457px - 300px / 2);margin:0;box-sizing:border-box}@media screen and (max-width:1274px){html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{padding:2em}}@media screen and (max-width:450px){html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{width:100%}}html body[for=html-export]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .markdown-preview{left:50%;transform:translateX(-50%)}html body[for=html-export]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .md-sidebar-toc{display:none}
/* Please visit the URL below for more information: */
/*   https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */

      </style>
      <!-- The content below will be included at the end of the <head> element. --><script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function () {
    // your code here
  });
</script></head><body for="html-export">
    
    
      <div class="crossnote markdown-preview  ">
      
<h1 id="前端面试题总结---2023年10月11日11点23分--">前端面试题总结 <!-- 2023年10月11日11点23分 --> </h1>
<h2 id="css">CSS </h2>
<p><strong>介绍一下标准的CSS的盒子模型？与低版本IE的盒子模型有什么不同的</strong></p>
<ul>
<li>标准盒子模型：宽度=内容的宽度（content）+ border + paddin + margin</li>
<li>低版本IE盒子模型：宽度=内容宽度（content+border+padding）+ margin</li>
</ul>
<p><strong>BFC/IFC</strong></p>
<ul>
<li>BFC（Block Formatting Context）叫做“块级格式化上下文"
<ul>
<li>几个特征
<ol>
<li>内部的盒子会在垂直方向，一个个地放置；</li>
<li>盒子垂直方向的距离由margin决定，属于同一个BFC的两个相邻Box的上下margin会发生重叠；</li>
<li>每个元素的左边，与包含的盒子的左边相接触，即使存在浮动也是如此；</li>
<li>BFC的区域不会与float重叠；</li>
<li>BFC就是页面上的一个隔离的独立容器，容器里面的子元素不会影响到外面的元素，反之也如此；</li>
<li>计算BFC的高度时，浮动元素也参与计算。</li>
</ol>
</li>
<li>触发条件
<ol>
<li>float的属性不为none；</li>
<li>position为absolute或fixed；</li>
<li>display为inline-block，table-cell，table-caption，flex；</li>
<li>overflow不为visible</li>
</ol>
</li>
</ul>
</li>
<li>IFC（inline Formatting Context）叫做“行级格式化上下”
<ul>
<li>几个特征
<ol>
<li>内部的盒子会在水平方向，一个个地放置；</li>
<li>IFC的高度，由里面最高盒子的高度决定；</li>
<li>一行不够放置的时候会自动切换到下一行；</li>
</ol>
</li>
</ul>
</li>
</ul>
<p><strong>position的值？</strong></p>
<ul>
<li>static（默认）：按照正常文档流进行排列；</li>
<li>relative（相对定位）：不脱离文档流，参考自身静态位置通过 top, bottom,left, right 定位；</li>
<li>absolute(绝对定位)：参考距其最近一个不为static的父级元素通过top, bottom, left, right 定位；</li>
<li>fixed(固定定位)：所固定的参照对像是可视窗口。</li>
</ul>
<p><strong>说一下流式布局与响应式布局</strong></p>
<ol>
<li>
<p>响应式布局就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。这个概念是为解决移动互联网浏览而诞生的。比如媒体查询</p>
<ul>
<li>优点
<ol>
<li>面对不同分辨率设备灵活性强</li>
<li>能够快捷解决多设备显示适应问题</li>
</ol>
</li>
<li>缺点
<ol>
<li>不能完全兼容所有浏览器，代码累赘，会出现隐藏无用的元素,加载时间加长</li>
<li>一定程度上改变了网站原有的布局结构，会出现用户混淆的情况。</li>
</ol>
</li>
</ul>
</li>
<li>
<p>流式布局就是页面中元素的宽度按照屏幕分辨率自动进行适配调整，它可以保证当前屏幕分辨率发生改变的时候，页面中的元素大小也可以跟着改变，所以流式布局是移动端开发常用的一种布局</p>
<blockquote>
<p>设计方法：使用%百分比定义宽度，高度大都是用px来固定住，可以根据可视区域 (viewport) 和父元素的实时尺寸进行调整，尽可能的适应各种分辨率。往往配合 max-width/min-width 等属性控制尺寸流动范围以免过大或者过小影响阅读</p>
</blockquote>
</li>
</ol>
<p><strong>CSS3有哪些新特性？</strong></p>
<ol>
<li>RGBA和透明度</li>
<li>background-image background-origin(content-box/padding-box/border-box) background-size background-repeat</li>
<li>word-wrap（对长的不可分割单词换行）word-wrap：break-word</li>
<li>文字阴影：text-shadow： 5px 5px 5px #FF0000;（水平阴影，垂直阴影，模糊距离，阴影颜色）</li>
<li>font-face属性：定义自己的字体</li>
<li>圆角（边框半径）：border-radius 属性用于创建圆角</li>
<li>边框图片：border-image: url(border.png) 30 30 round</li>
<li>盒阴影：box-shadow: 10px 10px 5px #888888</li>
<li>媒体查询：定义两套css，当浏览器的尺寸变化时会采用不同的属性</li>
</ol>
<p><strong>请解释一下CSS3的flexbox（弹性盒布局模型）,以及适用场景？</strong></p>
<ul>
<li>该布局模型的目的是提供一种更加高效的方式来对容器中的条目进行布局、对齐和分配空间。在传统的布局方式中，block 布局是把块在垂直方向从上到下依次排列的；而 inline 布局则是在水平方向来排列。弹性盒布局并没有这样内在的方向限制，可以由开发人员自由操作。</li>
<li>试用场景：弹性布局适合于移动前端开发，在Android和ios上也完美支持。</li>
</ul>
<p><strong>用纯CSS创建一个三角形的原理是什么？</strong></p>
<ol>
<li>把元素的宽度、高度设为0。</li>
<li>设置边框样式。<pre data-role="codeBlock" data-info="css" class="language-css css"><code><span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token property">border-top</span><span class="token punctuation">:</span> <span class="token number">40</span><span class="token unit">px</span> solid <span class="token color">transparent</span><span class="token punctuation">;</span>
<span class="token property">border-left</span><span class="token punctuation">:</span> <span class="token number">40</span><span class="token unit">px</span> solid <span class="token color">transparent</span><span class="token punctuation">;</span>
<span class="token property">border-right</span><span class="token punctuation">:</span> <span class="token number">40</span><span class="token unit">px</span> solid <span class="token color">transparent</span><span class="token punctuation">;</span>
<span class="token property">border-bottom</span><span class="token punctuation">:</span> <span class="token number">40</span><span class="token unit">px</span> solid <span class="token hexcode color">#ff0000</span><span class="token punctuation">;</span>
</code></pre></li>
</ol>
<p><strong>display:none与visibility：hidden的区别？</strong></p>
<ul>
<li>display：none 不显示对应的元素，在文档布局中不再分配空间（回流+重绘）</li>
<li>visibility：hidden 隐藏对应元素，在文档布局中仍保留原来的空间（重绘）</li>
</ul>
<p><strong>回流/重排(reflow)和重绘(repaint)</strong></p>
<ul>
<li>回流/重排：意味着元素的内容、结构、位置或尺寸发生了变化，需要重新计算样式和渲染树；</li>
<li>重绘：意味着元素发生的改变只影响了节点的一些样式（背景色，边框颜色，文字颜色等），只需要应用新样式绘制这个元素就可以了；</li>
<li>区别</li>
</ul>
<blockquote>
<p>他们的区别很大：<br>
回流必将引起重绘，而重绘不一定会引起回流。比如：只有颜色改变的时候就只会发生重绘而不会引起回流<br>
当页面布局和几何属性改变时就需要回流<br>
比如：添加或者删除可见的DOM元素，元素位置改变，元素尺寸改变——边距、填充、边框、宽度和高度，内容改变</p>
</blockquote>
<ul>
<li>回流的几种优化方式</li>
</ul>
<ol>
<li>直接改变className,如果动态改变样式，则使用cssText(没有优化的浏览器可以考虑)；</li>
<li>让要操作的元素进行'离线处理'，处理完后一起更新；
<ul>
<li>使用DocumentFragment进行缓存操作，引发一次回流和重绘；</li>
<li>使用display:none技术，只引发两次回流和重绘；</li>
<li>使用cloneNode(true or false)和replaceChild技术，引发一次回流和重绘；</li>
</ul>
</li>
<li>不要经常访问会引起浏览器flush队列的属性，如果确实要访问，就利用缓存；</li>
<li>让元素脱离动画流，减少回流的Render tree的规模；</li>
</ol>
<p><strong>设置元素浮动后，该元素的display值是多少？</strong></p>
<ul>
<li>自动变成display:block</li>
</ul>
<p><strong>::before 和 :after中双冒号和单冒号有什么区别？解释一下这2个伪元素的作用</strong></p>
<ol>
<li>单冒号(:)用于CSS3伪类，双冒号(::)用于CSS3伪元素。</li>
<li>::before就是以一个子元素的存在，定义在元素主体内容之前的一个伪元素。并不存在于dom之中，只存在在页面之中。</li>
</ol>
<p><strong>怎么让Chrome支持小于12px 的文字？</strong></p>
<pre data-role="codeBlock" data-info="css" class="language-css css"><code><span class="token selector">p</span><span class="token punctuation">{</span><span class="token property">font-size</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token unit">px</span><span class="token punctuation">;</span><span class="token property">-webkit-transform</span><span class="token punctuation">:</span><span class="token function">scale</span><span class="token punctuation">(</span><span class="token number">0.8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span> <span class="token comment">/*0.8是缩放比例*/</span>
</code></pre><p><strong>CSS 单位</strong><br>
总共列了 17 个单位：</p>
<ul>
<li>% 百分比、cm 里面、mm 毫米、px 像素（计算机屏幕上的一个点）、in 英寸、pt 磅 rgb(x,x,x) rgb(x%,x%,x%) #rrggbb（十六进制）</li>
<li>em：1em 等于当前字体尺寸（继承父元素的字体尺寸）</li>
<li>rem：r 为 root，1rem 等于根元素字体尺寸（继承 html 的字体尺寸）</li>
<li>vh：1vh 等于可视窗口高度的 1/100</li>
<li>vw: 1vw 等于可视窗口宽度的 1/100</li>
<li>vmin：可视窗口宽高更小的值的 1/100</li>
<li>vmax：可视窗口宽高更大的值的 1/100</li>
<li>ex：当前字体的一个 x-height，一般为当前字体的一个 em 的一半，因为一个 'x' 字母一般为字体大小的一半</li>
<li>ch：设置 width:40ch 表示这个宽度可以容纳 40 个特定字体的字符</li>
</ul>
<p><strong>rem 布局的优缺点</strong></p>
<ul>
<li>相对于 em 的好处是：不会发生逐渐增大或者减小字体尺寸的情况，因为始终继承根元素的字体尺寸；<br>
rem 单位不仅可应用于字体大小，还可以用于设定宽高等其他大小，使页面可以适配不同屏幕尺寸。</li>
<li>rem 一般只用于移动端。</li>
</ul>
<p><strong>CSS实现水平垂直居中的几种方法</strong></p>
<ol>
<li>绝对定位元素的居中实现<pre data-role="codeBlock" data-info="css" class="language-css css"><code><span class="token selector"><span class="token class">.center-vertical</span></span><span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100</span><span class="token unit">px</span><span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100</span><span class="token unit">px</span><span class="token punctuation">;</span>
    <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
    <span class="token property">top</span><span class="token punctuation">:</span> <span class="token number">50</span><span class="token unit">%</span><span class="token punctuation">;</span>
    <span class="token property">left</span><span class="token punctuation">:</span> <span class="token number">50</span><span class="token unit">%</span><span class="token punctuation">;</span>
    <span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">-50</span><span class="token unit">px</span><span class="token punctuation">;</span> <span class="token comment">/*高度的一半*/</span>
    <span class="token property">margin-left</span><span class="token punctuation">:</span> <span class="token number">-50</span><span class="token unit">px</span><span class="token punctuation">;</span> <span class="token comment">/*宽度的一半*/</span>
<span class="token punctuation">}</span>
<span class="token comment">/*
    优点：兼容性好
    缺点：需要提前知道元素的尺寸。如果不知道元素尺寸，这个时候就需要JS获取了。
*/</span>
<span class="token comment">/*CSS3.0的兴起，使这个问题有了更好的解决方法，就是使用 transform 代替 margin */</span>
<span class="token selector"><span class="token class">.content</span></span><span class="token punctuation">{</span>
    <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
    <span class="token property">top</span><span class="token punctuation">:</span> <span class="token number">50</span><span class="token unit">%</span><span class="token punctuation">;</span>
    <span class="token property">left</span><span class="token punctuation">:</span> <span class="token number">50</span><span class="token unit">%</span><span class="token punctuation">;</span>
    <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translate</span><span class="token punctuation">(</span> <span class="token number">-50</span><span class="token unit">%</span><span class="token punctuation">,</span> <span class="token number">-50</span><span class="token unit">%</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/*
    优点：无论绝对定位元素的尺寸是多少，它都是水平垂直居中显示的。
    缺点：就是兼容性问题。
*/</span>
</code></pre></li>
<li>margin: auto;实现绝对定位元素的居中<pre data-role="codeBlock" data-info="css" class="language-css css"><code><span class="token selector"><span class="token class">.center-vertical</span></span><span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100</span><span class="token unit">px</span><span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100</span><span class="token unit">px</span><span class="token punctuation">;</span>
    <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
    <span class="token property">top</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">left</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">right</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">bottom</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/*注意：上下左右均为 0 位置绝对定位。margin: auto;*/</span>
</code></pre></li>
<li>CSS3.0弹性布局<pre data-role="codeBlock" data-info="css" class="language-css css"><code><span class="token selector"><span class="token class">.parent-element</span></span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span><span class="token comment">/*定义父元素垂直居中*/</span>
    <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span><span class="token comment">/*定义父元素水平居中*/</span>
<span class="token punctuation">}</span>
</code></pre></li>
<li>display:table实现<pre data-role="codeBlock" data-info="css" class="language-css css"><code><span class="token selector"><span class="token class">.parent</span></span><span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">300</span><span class="token unit">px</span><span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">300</span><span class="token unit">px</span><span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token color">orange</span><span class="token punctuation">;</span>
    <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> table<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token class">.child</span></span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> table-cell<span class="token punctuation">;</span>
    <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token color">yellow</span><span class="token punctuation">;</span>
    <span class="token property">vertical-align</span><span class="token punctuation">:</span> middle<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></li>
</ol>
<p><strong>Flex 弹性盒布局</strong></p>
<ol>
<li>
<p>CSS3弹性盒布局的理解：<br>
web应用有不同设备尺寸和分辨率，这时需要响应式界面设计来满足复杂的布局需求，Flex弹性盒模型的优势在于开发人员只是声明布局应该具有的行为，而不需要给出具体的实现方式，浏览器负责完成实际布局。</p>
</li>
<li>
<p>容器的属性</p>
<pre data-role="codeBlock" data-info="css" class="language-css css"><code><span class="token comment">/*主轴的方向*/</span>
<span class="token property">flex-direction</span><span class="token punctuation">:</span> row | row-reverse | column | column-reverse<span class="token punctuation">;</span>
row（默认值）：主轴为水平方向，起点在左端。
row-reverse：主轴为水平方向，起点在右端。
column：主轴为垂直方向，起点在上沿。
column-reverse：主轴为垂直方向，起点在下沿。

<span class="token comment">/*换行属性*/</span>
<span class="token property">flex-wrap</span><span class="token punctuation">:</span> nowrap | wrap | wrap-reverse<span class="token punctuation">;</span>
nowrap（默认）：不换行。
wrap：换行，第一行在上方。
wrap-reverse：换行，第一行在下方。

<span class="token comment">/*简写：方向 + 换行*/</span>
<span class="token property">flex-flow</span><span class="token punctuation">:</span> &lt;flex-direction&gt; || &lt;flex-wrap&gt;<span class="token punctuation">;</span>

<span class="token comment">/*主轴对齐方式*/</span>
<span class="token property">justify-content</span><span class="token punctuation">:</span> flex-start | flex-end | center | space-between | space-around<span class="token punctuation">;</span>
flex-start（默认值）：左对齐
flex-end：右对齐
center： 居中
space-between：两端对齐，项目之间的间隔都相等。
space-around：每个项目两侧的间隔相等。所以，项目之间的间隔比项目与边框的间隔大一倍。

<span class="token comment">/*交叉轴对齐方式*/</span>
<span class="token property">align-items</span><span class="token punctuation">:</span> flex-start | flex-end | center | baseline | stretch<span class="token punctuation">;</span>
flex-start：交叉轴的起点对齐。
flex-end：交叉轴的终点对齐。
center：交叉轴的中点对齐。
<span class="token property">baseline</span><span class="token punctuation">:</span> 项目的第一行文字的基线对齐。
stretch（默认值）：如果项目未设置高度或设为auto，将占满整个容器的高度。

</code></pre></li>
<li>
<p>项目的属性</p>
<pre data-role="codeBlock" data-info="css" class="language-css css"><code><span class="token comment">/*排列顺序，数值越小，排列越靠前，默认为0。*/</span>
<span class="token property">order</span><span class="token punctuation">:</span> &lt;integer&gt;<span class="token punctuation">;</span>

<span class="token comment">/*项目的放大比例,默认为0，即如果存在剩余空间，也不放大。*/</span>
<span class="token property">flex-grow</span><span class="token punctuation">:</span> &lt;number&gt;<span class="token punctuation">;</span> <span class="token comment">/* default 0 */</span>

<span class="token comment">/*项目的缩小比例,默认为1，即如果空间不足，该项目将缩小。*/</span>
<span class="token property">flex-shrink</span><span class="token punctuation">:</span> &lt;number&gt;<span class="token punctuation">;</span> <span class="token comment">/* default 1 */</span>

<span class="token comment">/*项目占据的空间,默认值为auto，即项目的本来大小*/</span>
<span class="token property">flex-basis</span><span class="token punctuation">:</span> &lt;length&gt; | auto<span class="token punctuation">;</span> <span class="token comment">/* default auto */</span>

<span class="token comment">/*简写：flex-grow, flex-shrink 和 flex-basis*/</span>
<span class="token property">flex</span><span class="token punctuation">:</span> none | [ &lt;<span class="token string">'flex-grow'</span>&gt; &lt;<span class="token string">'flex-shrink'</span>&gt;? || &lt;<span class="token string">'flex-basis'</span>&gt; ]
</code></pre></li>
</ol>
<hr>
<h2 id="javascript">JavaScript </h2>
<p><strong>js中的闭包</strong></p>
<ul>
<li><strong>我们首先知道闭包有3个特性：</strong>
<ol>
<li>函数嵌套函数</li>
<li>函数内部可以引用函数外部的参数和变量</li>
<li>参数和变量不会被垃圾回收机制回收</li>
</ol>
</li>
<li><strong>闭包的好处与坏处</strong>
<ul>
<li>好处
<ol>
<li>保护函数内的变量安全 ，实现封装，防止变量流入其他环境发生命名冲突</li>
<li>在内存中维持一个变量，可以做缓存（但使用多了同时也是一项缺点，消耗内存）</li>
<li>匿名自执行函数可以减少内存消耗</li>
</ol>
</li>
<li>坏处</li>
</ul>
<ol>
<li>其中一点上面已经有体现了，就是被引用的私有变量不能被销毁，增大了内存消耗，造成内存泄漏，解决方法是可以在使用完变量后手动为它赋值为null；</li>
<li>其次由于闭包涉及跨域访问，所以会导致性能损失，我们可以通过把跨作用域变量存储在局部变量中，然后直接访问局部变量，来减轻对执行速度的影响</li>
</ol>
</li>
</ul>
<p><strong>JavaScript中数组，内置对象的常用方法</strong></p>
<ol>
<li>
<p>join()——将数组中的所有元素转化为字符串并连接在一起，返回最后生成的字符串。不修改原始数组</p>
</li>
<li>
<p>reverse()——将数组中的元素逆序，返回逆序后的数组。修改原始数组</p>
</li>
<li>
<p>sort()——将数组元素进行排序，返回排序后的数组。默认以字母表顺序排序。修改原始数组</p>
</li>
<li>
<p>concat()——创建并返回一个新数组。不修改原始数组</p>
</li>
<li>
<p>slice()——对数组进行分离，并返回一个子数组。不修改原始数组</p>
<blockquote>
<p>第1个参数表示起始索引<br>
第2个参数表示结束索引(返回数组不包含结束索引对应的元素值)<br>
如果没有第2个参数，则表示取值到最后一个索引。正值表示正向索引，负值表示反向索引</p>
</blockquote>
</li>
<li>
<p>splice()——从数组中删除和插入一些元素。修改原始数组</p>
<blockquote>
<ol>
<li>前2个参数指定了要删除的数组元素<br>
 第1个参数表示需要删除元素的起始索引值<br>
 第2个参数表示需要删除的个数 如果省略则表示删除起始索引后的所有元素</li>
<li>后面的参数指定需要插入的元素</li>
</ol>
</blockquote>
</li>
<li>
<p>push()——在数组的尾部添加一个或多个元素，并返回数组新的长度，修改原始数组</p>
</li>
<li>
<p>pop()——在数组的尾部删除一个元素，并返回弹出的元素值，修改原始数组</p>
</li>
<li>
<p>unshift()——在数组的头部添加，返回新的数组长度，修改原始数组</p>
</li>
<li>
<p>shift()——在数组的头部删除，返回删除的数组元素，修改原始数组</p>
</li>
<li>
<p>toString()——返回一个字符串</p>
</li>
<li>
<p>forEach()——方法从头至尾遍历数组，为每个元素调用指定的函数</p>
<blockquote>
<p>forEach()没有像for循环中使用的相应的break语句，如果要提前终止，可以做放到try/catch中处理</p>
</blockquote>
</li>
<li>
<p>map()——方法为数组的每个元素调用指定的函数，并返回一个新数组</p>
</li>
<li>
<p>filter()——方法为数组的每个元素调用指定的函数，并返回筛选出的新数组</p>
</li>
<li>
<p>find()——方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。</p>
</li>
<li>
<p>findIndex()——方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。</p>
</li>
<li>
<p>every()——方法为数组的每个元素调用指定的函数，并返回true或false。当有一个调用返回false时，every()就会返回false；只有当所有调用都是true时，every()才返回true</p>
</li>
<li>
<p>some()——方法为数组的每个元素调用指定的函数，并返回true或false。当有一个调用返回true时，some()就会返回true；只有当所有调用都是false时，some()才返回false</p>
</li>
<li>
<p>reduce()——对数组的元素对调用指定的函数，并返回最终生成的单个值</p>
<blockquote>
<p>第1个参数指定调用的函数<br>
第2个参数为可选参数，指定传递给函数的初始值，当不指定值时，使用数组的第1个元素作为初始值</p>
</blockquote>
</li>
<li>
<p>indexOf()——搜索整个数组中给定值的元素，返回找到的第1个元素的索引，如果找不到，则返回-1</p>
<blockquote>
<p>第1个参数为需要搜索的值<br>
第2个参数是可选的，指定开始搜索的索引位置</p>
</blockquote>
</li>
<li>
<p>includes()——方法用于判断数组是否包含指定的子数组。如果找到匹配的数组则返回 true，否则返回 false。</p>
</li>
<li>
<p>Array.isArray()——判断一个对象是否是数组</p>
</li>
</ol>
<p><strong>说说浏览器事件循环机制</strong></p>
<blockquote>
<p>JavaScript代码的执行过程中，除了依靠函数调用栈来搞定函数的执行顺序外，还依靠任务队列(task queue)来搞定另外一些代码的执行。整个执行过程，我们称为事件循环过程。一个线程中，事件循环是唯一的，但是任务队列可以拥有多个。任务队列又分为macro-task（宏任务）与micro-task（微任务），在最新标准中，它们被分别称为task与jobs。</p>
</blockquote>
<ul>
<li>
<p>macro-task大概包括：</p>
<ul>
<li>script(整体代码)</li>
<li>setTimeout</li>
<li>setInterval</li>
<li>setImmediate</li>
<li>I/O</li>
<li>UI render</li>
</ul>
</li>
<li>
<p>micro-task大概包括:</p>
<ul>
<li>process.nextTick</li>
<li>Promise</li>
<li>Async/Await(实际就是promise)</li>
<li>MutationObserver(html5新特性)</li>
</ul>
</li>
</ul>
<blockquote>
<p>执行过程为执行宏任务，然后执行该宏任务产生的微任务，若微任务在执行过程中产生了新的微任务，则继续执行微任务，微任务执行完毕后，再回到宏任务中进行下一轮循环。</p>
</blockquote>
<p><strong>下面函数执行结果</strong></p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token known-class-name class-name">Promise</span><span class="token punctuation">.</span><span class="token method function property-access">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token arrow operator">=&gt;</span><span class="token punctuation">{</span>
    <span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">'Promise1'</span><span class="token punctuation">)</span>
    <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token arrow operator">=&gt;</span><span class="token punctuation">{</span>
        <span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">'setTimeout2'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token arrow operator">=&gt;</span><span class="token punctuation">{</span>
    <span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">'setTimeout1'</span><span class="token punctuation">)</span>
    <span class="token known-class-name class-name">Promise</span><span class="token punctuation">.</span><span class="token method function property-access">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token arrow operator">=&gt;</span><span class="token punctuation">{</span>
        <span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">'Promise2'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// Promise1</span>
<span class="token comment">// setTimeout1</span>
<span class="token comment">// Promise2</span>
<span class="token comment">// setTimeout2</span>
</code></pre><p><strong>js的几种设计模式</strong></p>
<ol>
<li>工厂模式
<blockquote>
<ul>
<li>简单的工厂模：可以理解为解决多个相似的问题(提示框，只是提示的文字需要修改)</li>
<li>复杂的工厂模式：将其成员对象的实列化推迟到子类中，子类可以重写父类接口方法以便创建的时候指定自己的对象类型,各种UI组件，根据你要的类型不同（比如：按钮，提示框，表格等）</li>
</ul>
</blockquote>
</li>
<li>单例模式
<blockquote>
<p>两个特点：一个类只有一个实例，并且提供可全局访问点 全局对象是最简单的单例模式：window<br>
demo:登录弹出框只需要实例化一次，就可以反复用了</p>
</blockquote>
</li>
<li>模块模式
<blockquote>
<p>模块模式的思路是为单体模式添加私有变量和私有方法能够减少全局变量的使用<br>
demo:返回对象的匿名函数。在这个匿名函数内部，先定义了私有变量和函数</p>
</blockquote>
</li>
<li>代理模式
<blockquote>
<p>代理对象可以代替本体被实例化，并使其可以被远程访问<br>
demo: 虚拟代理实现图片的预加载</p>
</blockquote>
</li>
<li>命令模式
<blockquote>
<p>有时候需要向某些对象发送请求，但是并不知道请求的接收者是谁，也不知道请求的操作是什么，此时希望用一种松耦合的方式来设计程序代码;使得请求发送者和请求接受者消除彼此代码中的耦合关系。<br>
demo：几个按钮绑定不同的事件，然后bindEvent(el, event);</p>
</blockquote>
</li>
<li>发布订阅模式介绍
<blockquote>
<p>发布—订阅模式又叫观察者模式，它定义了对象间的一种一对多的关系，让多个观察者对象同时监听某一个主题对象，当一个对象发生改变时，所有依赖于它的对象都将得到通知。<br>
demo: 比如你向买房，只要把手机给房产中介，房产中介一有消息就发布消息。</p>
</blockquote>
</li>
<li>适配器模式
<blockquote>
<p>适配器模式主要解决两个接口之间不匹配的问题，不会改变原有的接口，而是由一个对象对另一个对象的包装。<br>
demo:两个地图（2个类），他们有一个共同方法但是名字不同，这时候需要定义适配器类, 对其中的一个类进行封装。</p>
</blockquote>
</li>
</ol>
<p><strong>原型链是什么?</strong></p>
<blockquote>
<p>用new运算符加上函数的调用，调用的结果就是一个对象，new出来的这个对象我们称他为实例<br>
prototype（原型）是一个指针指向了一个原型对象，这个对象里面存放所有的实例共享的属性和方法<br>
实例的__proto__指向了构造函数的prototype，构造函数是object的实例，构造函数的prototype下的__proto__指向了object的prototype 我们称他为原型链</p>
</blockquote>
<p><strong>new的时候做了哪些操作</strong></p>
<ol>
<li>创建一个新对象</li>
<li>将构造函数的作用域赋值给新对象（this指向这个新对象）</li>
<li>执行构造函数中的代码（为这个新对象添加属性）</li>
<li>返回新对象</li>
</ol>
<p><strong>this和super的区别</strong></p>
<ol>
<li>属性的区别：
<ul>
<li>this访问本类中的属性，如果本类没有此属性则从父类中继续查找。</li>
<li>super访问父类中的属性。</li>
</ul>
</li>
<li>方法的区别：
<ul>
<li>this访问本类中的方法，如果本类没有此方法则从父类中继续查找。</li>
<li>super访问父类中的方法。</li>
</ul>
</li>
<li>构造的区别：
<ul>
<li>this调用本类构造，必须放在构造方法的首行。</li>
<li>super调用父类构造，必须放在子类构造方法首行。</li>
</ul>
</li>
<li>其他区别：
<ul>
<li>this表示当前对象。</li>
<li>super不能表示当前对象</li>
</ul>
</li>
</ol>
<p><strong>JS 时区时间转换</strong></p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token comment">/*将本地时间转换为东八区时间*/</span>
<span class="token keyword keyword-var">var</span> timezone <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span> <span class="token comment">//目标时区时间，东八区</span>
<span class="token keyword keyword-var">var</span> offset_GMT <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">getTimezoneOffset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 本地时间和格林威治的时间差，单位为分钟</span>
<span class="token keyword keyword-var">var</span> nowDate <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 本地时间距 1970 年 1 月 1 日午夜（GMT 时间）之间的毫秒数</span>
<span class="token keyword keyword-var">var</span> targetDate <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>nowDate <span class="token operator">+</span> offset_GMT <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">1000</span> <span class="token operator">+</span> timezone <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">"东8区现在是："</span> <span class="token operator">+</span> targetDate<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p><strong>说一下apply、call与bind</strong></p>
<ol>
<li>共同点：
<ul>
<li>都是函数对象的一个方法，主要作用都是改变函数体内部this的指向</li>
</ul>
</li>
<li>区别：
<ul>
<li>bind返回的是整个函数的方法并且不会调用函数、而apply、call会调用函数返回的是方法调用后返回的结果</li>
<li>bind方法并非立即执行；apply和call方法是立即执行函数</li>
<li>apply 第二个参数是一个数组，bind和call是参数序列</li>
</ul>
</li>
</ol>
<p><strong>JS 中 == 和 === 区别是什么？</strong></p>
<ol>
<li>
<p>对于string,number等基础类型，== 和 === 有区别</p>
<ul>
<li>不同类型间比较，==之比较“转化成同一类型后的值”看“值”是否相等，===如果类型不同，其结果就是不等。</li>
<li>同类型比较，直接进行“值”比较，两者结果一样。</li>
</ul>
</li>
<li>
<p>基础类型与高级类型，== 和 === 有区别</p>
<ul>
<li>对于==，将高级转化为基础类型，进行“值”比较。</li>
<li>因为类型不同，===结果为false。</li>
</ul>
</li>
<li>
<p>对于Array,Object等高级类型，== 和===没有区别</p>
<ul>
<li>进行“指针地址”比较。</li>
</ul>
</li>
</ol>
<p><strong>JS中的深拷贝与浅拷贝的区别？</strong></p>
<ul>
<li>深拷贝递归地复制新对象中的所有值或属性，而拷贝只复制引用。</li>
<li>在深拷贝中，新对象中的更改不会影响原始对象，而在浅拷贝中，新对象中的更改，原始对象中也会跟着改。</li>
<li>在深拷贝中，原始对象不与新对象共享相同的属性，而在浅拷贝中，它们具有相同的属性。</li>
</ul>
<p><strong>描述下cookie,sessionStorage,localStorage的差异</strong></p>
<ol>
<li>都是保存在浏览器端、且同源的</li>
<li>cookie大小4KB 左右,跟随请求(请求头),会占用带宽资源,但是若是用来判断用户是否在线这些挺方便,sessionStorage和localStorage虽然也有存储大小的限制，但比cookie大得多，可以达到5M或更大</li>
<li>数据有效期不同，sessionStorage：仅在当前浏览器窗口关闭之前有效；localStorage：始终有效，窗口或浏览器关闭也一直保存，因此用作持久数据；cookie：只在设置的cookie过期时间之前有效，即使窗口关闭或浏览器关闭</li>
<li>作用域不同，sessionStorage不在不同的浏览器窗口中共享，即使是同一个页面；localstorage在所有同源窗口中都是共享的；cookie也是在所有同源窗口中都是共享的</li>
</ol>
<p><strong>ES6+你熟悉么,用过哪些特性?</strong></p>
<ul>
<li>箭头函数</li>
<li>类及引入导出和继承( class/import/export/extends)</li>
<li>字符串模板</li>
<li>Promise</li>
<li>let,const</li>
<li>async/await</li>
<li>默认参数/参数或变量解构装饰器</li>
<li>Array.inclueds/String.padStart|String.padEnd/Object.assign</li>
</ul>
<p><strong>js中的箭头函数和普通函数有什么区别</strong></p>
<ol>
<li>样式不同，箭头函数是 =&gt;，普通函数是 function；</li>
<li>箭头函数不能作为构造函数使用，也就不能使用 new 关键字；</li>
<li>箭头函数不绑定 arguments，可以考虑用剩余参数代替；</li>
<li>箭头函数会捕获其所在上下文的 this 值，作为自己的 this 值，定义的时候就确定了；</li>
<li>call、apply、bind 并不会影响 this 的指向；</li>
<li>箭头函数没有原型属性；</li>
<li>箭头函数不能当作 Generator 函数，不能使用 yield 关键字；</li>
</ol>
<p><strong>var、let、const之间的区别?</strong></p>
<ul>
<li>var
<ol>
<li>var声明变量可以重复声明，而let不可以重复声明</li>
<li>var是不受限于块级的，而let是受限于块级</li>
<li>var会与window相映射（会挂一个属性），而let不与window相映射</li>
</ol>
</li>
<li>let
<ol>
<li>会产生块级作用域,不会造成变量提升,无法重新声明(但可以重新赋值);</li>
</ol>
</li>
<li>const
<ol>
<li>是只读的,若是基本数据类型,具有不变性(无法重新赋值改动)</li>
<li>引用对象可以调整内部值(可能设计的时候没有考虑周全!）</li>
</ol>
</li>
</ul>
<p><strong>谈谈你对 Promise 的理解?</strong></p>
<ol>
<li>
<p>Promise 是一个构造函数，我们可以通过该构造函数来生成Promise的实例。Promise 构造函数是同步执行的，promise.then 中的函数是异步执行的。</p>
</li>
<li>
<p>Promise 状态有三：pending（等待）、resolved（成功）、rejected（失败）。状态改变只能是 pending-&gt;resolved 或者 pending-&gt;rejected，状态一旦改变则不能再变</p>
</li>
<li>
<p>Promise 是对回调函数的一种封装，解决对调地狱的问题，我们可以通过Promise将自己的程序以同步的方式表达出来，从而可以解决代码臃肿及可读性差的问题。</p>
</li>
<li>
<p>axios采用Promise对象，发送ajax请求，获取数据，利用async和awiat方式类同步获取数据</p>
</li>
<li>
<p>Promise虽然解决了我们项目开发中的很多问题，但我们也不能无脑的滥用。比如Promise.all，如果参数中promise有一个失败（rejected），则此实例回调必然失败（reject），就不会再执行then方法的回调了。在实际中可能只是一个不关键的数据加载失败，往往会导致其他所有的数据不会显示，使得项目的容错性大大降低。所以我个人在开发过程中只会在必须依赖这几个步骤全部加载成功后才能继续向下执行的场景中采用它，比如图片的预加载功能。</p>
</li>
</ol>
<blockquote>
<ol>
<li>成功调用 resolve，失败调用 reject</li>
<li>.then 获取结果，.catch 捕获异常。捕获异常还可通过 .then 的第二个参数</li>
<li>.finally 无论成功失败都一定会调用</li>
<li>多个并发的请求，用 Promise.all()</li>
<li>只有p1、p2、p3的状态都变成fulfilled，p的状态才会变成fulfilled，此时p1、p2、p3的返回值组成一个数组，传递给p的回调函数。</li>
<li>只要p1、p2、p3之中有一个被rejected，p的状态就变成rejected，此时第一个被reject的实例的返回值，会传递给p的回调函数。</li>
</ol>
</blockquote>
<p><strong>说一下Set,Map的区别</strong></p>
<ol>
<li>
<p>简述：</p>
<ul>
<li>Set 和 Map 主要的应用场景在于 数据重组 和 数据储存。</li>
<li>Set 是一种叫做集合的数据结构，Map 是一种叫做字典的数据结构。</li>
</ul>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token comment">// 去重数组</span>
<span class="token known-class-name class-name">Array</span><span class="token punctuation">.</span><span class="token keyword module keyword-from">from</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token comment">// 简化</span>
<span class="token punctuation">[</span><span class="token spread operator">...</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">]</span>
</code></pre></li>
<li>
<p>区别：</p>
<ul>
<li>共同点：Set、Map 可以储存不重复的值</li>
<li>不同点：Map 是以 [value, value]的形式储存元素，Map 是以 [key, value] 的形式储存</li>
</ul>
</li>
<li>
<p>总结：</p>
<ul>
<li>
<p>Set：</p>
<ul>
<li>成员唯一、无序且不重复。</li>
<li>[value, value]，键值与键名是一致的（或者说只有键值，没有键名）。</li>
<li>可以遍历，方法有：add、delete、has。</li>
</ul>
</li>
<li>
<p>Map：</p>
<ul>
<li>本质上是键值对的集合，类似集合。</li>
<li>可以遍历，方法很多可以跟各种数据格式转换。</li>
</ul>
</li>
<li>
<p>WeakSet：</p>
<ul>
<li>成员都是对象。</li>
<li>成员都是弱引用，可以被垃圾回收机制回收，可以用来保存DOM节点，不容易造成内存泄漏。</li>
<li>不能遍历，方法有add、delete、has。</li>
</ul>
</li>
<li>
<p>WeakMap：</p>
<ul>
<li>只接受对象作为键名（null除外），不接受其他类型的值作为键名。</li>
<li>键名是弱引用，键值可以是任意的，键名所指向的对象可以被垃圾回收，此时键名是无效的。</li>
<li>不能遍历，方法有get、set、has、delete。</li>
</ul>
</li>
</ul>
</li>
</ol>
<p><strong>说说常见的几种去重方式</strong></p>
<ol>
<li>利用ES6 Set去重（ES6中最常用）</li>
<li>利用for嵌套for，然后splice去重（ES5中最常用）双层循环，外层循环元素，内层循环时比较值。值相同时，则删去这个值。</li>
<li>利用indexOf去重 新建一个空的结果数组，for 循环原数组，判断结果数组是否存在当前元素，如果有相同的值则跳过，不相同则push进数组。</li>
<li>利用sort() 排序方法，然后根据排序后的结果进行遍历及相邻元素比对。</li>
<li>利用includes() 检测数组是否有某个值</li>
<li>利用filter() + indexOf() 当前元素，在原始数组中的第一个索引==当前索引值，否则返回当前元素</li>
<li>利用递归去重</li>
</ol>
<p><strong>说一下es6中的Symbol</strong></p>
<ul>
<li>SymbolSymbol是一种基本类型。Symbol 通过调用symbol函数产生，它接收一个可选的名字参数，该函数返回的symbol是唯一的</li>
</ul>
<p><strong>说一下typeof和instanceof的缺点</strong></p>
<ol>
<li>typeof
<ul>
<li>判断null的结果为“object”,是javascript诞生就存在的bug</li>
<li>typeof 可以判断undefined,而 instanceof,判断会报错</li>
<li>typeof 无法判断Array 和Object，instanceof 可以</li>
<li>type 判断undefined 和null的区别（两个变量类型之间）</li>
</ul>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token keyword keyword-typeof">typeof</span> <span class="token keyword nil keyword-undefined">undefined</span> <span class="token comment">// "undefined"</span>
<span class="token keyword keyword-typeof">typeof</span> <span class="token keyword null nil keyword-null">null</span> <span class="token comment">// "object"</span>
<span class="token comment">//  undefined 和 null 之间要又 三等运算符</span>
<span class="token keyword nil keyword-undefined">undefined</span> <span class="token operator">==</span> <span class="token keyword null nil keyword-null">null</span> <span class="token comment">// true</span>
<span class="token keyword nil keyword-undefined">undefined</span> <span class="token operator">===</span> <span class="token keyword null nil keyword-null">null</span> <span class="token comment">// false</span>
<span class="token keyword nil keyword-undefined">undefined</span> <span class="token operator">!=</span> <span class="token keyword null nil keyword-null">null</span> <span class="token comment">// false</span>
<span class="token keyword nil keyword-undefined">undefined</span> <span class="token operator">!==</span> <span class="token keyword null nil keyword-null">null</span>  <span class="token comment">// true</span>
</code></pre></li>
<li>instanceof:
<ul>
<li>
<p>判断null 和undefined 的时候会报错</p>
</li>
<li>
<p>在判断字符串的时候，如果不是通过new 方式创建的字符串，得到的结果为fasle</p>
</li>
</ul>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token keyword keyword-let">let</span> str <span class="token operator">=</span> <span class="token string">'this is string'</span><span class="token punctuation">;</span> 
str <span class="token keyword keyword-instanceof">instanceof</span> <span class="token class-name">String</span> <span class="token comment">// 接口为false</span>
<span class="token keyword keyword-let">let</span> str2 <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">String</span><span class="token punctuation">(</span><span class="token string">'this is string'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 
str2 <span class="token keyword keyword-instanceof">instanceof</span> <span class="token class-name">String</span> <span class="token comment">// 接口为true</span>
</code></pre><ul>
<li>如果更改了对象的原型，那么得到结果也是不准确的</li>
</ul>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token keyword keyword-var">var</span> o <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">C</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
o <span class="token keyword keyword-instanceof">instanceof</span> <span class="token class-name">C</span><span class="token punctuation">;</span> <span class="token comment">// true，因为 Object.getPrototypeOf(o) === C.prototype</span>
<span class="token class-name">C</span><span class="token punctuation">.</span><span class="token property-access">prototype</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
o <span class="token keyword keyword-instanceof">instanceof</span> <span class="token class-name">C</span><span class="token punctuation">;</span> <span class="token comment">// false，C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.</span>
</code></pre><blockquote>
<p>需要注意的是，如果表达式 obj instanceof Foo 返回 true，则并不意味着该表达式会永远返回 true，因为 Foo.prototype 属性的值有可能会改变，改变之后的值很有可能不存在于 obj 的原型链上，这时原表达式的值就会成为 false。另外一种情况下，原表达式的值也会改变，就是改变对象 obj 的原型链的情况，虽然在目前的ES规范中，我们只能读取对象的原型而不能改变它，但借助于非标准的 <strong>proto</strong> 伪属性，是可以实现的。比如执行 obj.<strong>proto</strong> = {} 之后，obj instanceof Foo 就会返回 false 了。</p>
</blockquote>
</li>
</ol>
<p><strong>JavaScript 数组扁平化</strong><br>
ES 5 提供了内置的 flat 方法可以直接把数组扁平化，而无需借助第三方库。<br>
Array.prototype.flat() 特性总结：</p>
<ul>
<li>Array.prototype.flat() 用于将嵌套的数组扁平化，变成一维的数组。该方法返回一个新数组，对原数据没有影响。</li>
<li>不传参数时，默认“拉平”一层，可以传入一个整数，表示想要“拉平”的层数。</li>
<li>传入 参数&lt;=0 的整数将返回原数组，不“拉平”。</li>
<li>Infinity 关键字作为参数时，无论多少层嵌套，都会转为一维数组。</li>
<li>如果原数组有空位，Array.prototype.flat() 会跳过空位。</li>
</ul>
<p><strong>手写一个防抖函数</strong></p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token comment">// 定义防抖函数</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">debounce</span> <span class="token operator">=</span> <span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token parameter">fn<span class="token punctuation">,</span> wait<span class="token punctuation">,</span> immediate</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 自由变量，debounce执行完成被释放，time也不会被释放</span>
  <span class="token keyword keyword-let">let</span> time<span class="token punctuation">;</span>
  <span class="token comment">// 返回一个闭包，接受参数</span>
  <span class="token keyword control-flow keyword-return">return</span> <span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token spread operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 保存闭包被调用时的this</span>
    <span class="token keyword keyword-const">const</span> this_ <span class="token operator">=</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">;</span>
    <span class="token comment">// 清除上一次的定时器</span>
    <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>time<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token function">clearTimeout</span><span class="token punctuation">(</span>time<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token comment">// 配置开关</span>
    <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>immediate<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword keyword-const">const</span> action <span class="token operator">=</span> <span class="token operator">!</span>time<span class="token punctuation">;</span>
      <span class="token comment">// time没置空前因为time存在，所以fn不会执行</span>
      time <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      	fn<span class="token punctuation">.</span><span class="token method function property-access">apply</span><span class="token punctuation">(</span>this_<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// 每隔wait时间将time置为空</span>
        time <span class="token operator">=</span> <span class="token keyword null nil keyword-null">null</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span> wait<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>action<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        fn<span class="token punctuation">.</span><span class="token method function property-access">apply</span><span class="token punctuation">(</span>this_<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-else">else</span> <span class="token punctuation">{</span>
      <span class="token comment">// 不再是直接执行fn，在内部传递参数</span>
      time <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 通过apply修改fn的this</span>
        fn<span class="token punctuation">.</span><span class="token method function property-access">apply</span><span class="token punctuation">(</span>this_<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span> wait<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre><p><strong>手写一个Promise类</strong></p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token keyword keyword-class">class</span> <span class="token class-name">Promise2</span> <span class="token punctuation">{</span>
  state <span class="token operator">=</span> <span class="token string">"pending"</span>
  callbacks <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>

  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> fn <span class="token operator">!==</span> <span class="token string">"function"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword control-flow keyword-throw">throw</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"只接受函数作为参数！"</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token function">fn</span><span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token method function property-access">resolve</span><span class="token punctuation">.</span><span class="token method function property-access">bind</span><span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token method function property-access">reject</span><span class="token punctuation">.</span><span class="token method function property-access">bind</span><span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">state</span> <span class="token operator">!==</span> <span class="token string">"pending"</span><span class="token punctuation">)</span> <span class="token keyword control-flow keyword-return">return</span><span class="token punctuation">;</span>
    <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">state</span> <span class="token operator">=</span> <span class="token string">"fulfilled"</span>
    <span class="token function">nextTick</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">//遍历callbacks，调用所有的handle[0]</span>
      <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">callbacks</span><span class="token punctuation">.</span><span class="token method function property-access">forEach</span><span class="token punctuation">(</span><span class="token parameter">handle</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token keyword keyword-let">let</span> x
        <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> handle<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">"function"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token keyword control-flow keyword-try">try</span> <span class="token punctuation">{</span>
            x <span class="token operator">=</span> handle<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token method function property-access">call</span><span class="token punctuation">(</span><span class="token keyword nil keyword-undefined">undefined</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span>
          <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-catch">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            handle<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token method function property-access">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
          <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        handle<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token method function property-access">resolve</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function">reject</span><span class="token punctuation">(</span><span class="token parameter">reason</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">state</span> <span class="token operator">!==</span> <span class="token string">"pending"</span><span class="token punctuation">)</span> <span class="token keyword control-flow keyword-return">return</span><span class="token punctuation">;</span>
    <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">state</span> <span class="token operator">=</span> <span class="token string">"rejected"</span>
    <span class="token function">nextTick</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">//遍历callbacks，调用所有的handle[1]</span>
      <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">callbacks</span><span class="token punctuation">.</span><span class="token method function property-access">forEach</span><span class="token punctuation">(</span><span class="token parameter">handle</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token keyword keyword-let">let</span> x
        <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> handle<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">"function"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token keyword control-flow keyword-try">try</span> <span class="token punctuation">{</span>
            x <span class="token operator">=</span> handle<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token method function property-access">call</span><span class="token punctuation">(</span><span class="token keyword nil keyword-undefined">undefined</span><span class="token punctuation">,</span> reason<span class="token punctuation">)</span>
          <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-catch">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            handle<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token method function property-access">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
          <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        handle<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token method function property-access">resolve</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">succeed<span class="token operator">?</span><span class="token punctuation">,</span> fail<span class="token operator">?</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword keyword-const">const</span> handle <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> succeed <span class="token operator">===</span> <span class="token string">"function"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      handle<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> succeed
    <span class="token punctuation">}</span>
    <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> fail <span class="token operator">===</span> <span class="token string">"function"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      handle<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> fail
    <span class="token punctuation">}</span>
    handle<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Promise2</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token comment">//把函数推到 callbacks 里面</span>
    <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token property-access">callbacks</span><span class="token punctuation">.</span><span class="token method function property-access">push</span><span class="token punctuation">(</span>handle<span class="token punctuation">)</span>
    <span class="token keyword control-flow keyword-return">return</span> handle<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword module keyword-export">export</span> <span class="token keyword module keyword-default">default</span> <span class="token maybe-class-name">Promise2</span>

<span class="token keyword keyword-function">function</span> <span class="token function">nextTick</span><span class="token punctuation">(</span><span class="token parameter">fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>process <span class="token operator">!==</span> <span class="token keyword nil keyword-undefined">undefined</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword keyword-typeof">typeof</span> process<span class="token punctuation">.</span><span class="token property-access">nextTick</span> <span class="token operator">===</span> <span class="token string">"function"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword control-flow keyword-return">return</span> process<span class="token punctuation">.</span><span class="token method function property-access">nextTick</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-else">else</span> <span class="token punctuation">{</span>
    <span class="token keyword keyword-var">var</span> counter <span class="token operator">=</span> <span class="token number">1</span>
    <span class="token keyword keyword-var">var</span> observer <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">MutationObserver</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span>
    <span class="token keyword keyword-var">var</span> textNode <span class="token operator">=</span> <span class="token dom variable">document</span><span class="token punctuation">.</span><span class="token method function property-access">createTextNode</span><span class="token punctuation">(</span><span class="token known-class-name class-name">String</span><span class="token punctuation">(</span>counter<span class="token punctuation">)</span><span class="token punctuation">)</span>
    observer<span class="token punctuation">.</span><span class="token method function property-access">observe</span><span class="token punctuation">(</span>textNode<span class="token punctuation">,</span> <span class="token punctuation">{</span>
      <span class="token literal-property property">characterData</span><span class="token operator">:</span> <span class="token boolean">true</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    counter <span class="token operator">=</span> counter <span class="token operator">+</span> <span class="token number">1</span>
    textNode<span class="token punctuation">.</span><span class="token property-access">data</span> <span class="token operator">=</span> <span class="token known-class-name class-name">String</span><span class="token punctuation">(</span>counter<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><hr>
<h2 id="vue20">Vue2.0 </h2>
<p><strong>组件通信有几种方式</strong></p>
<ol>
<li>父组件向子组件通信，子组件通过 props 属性，绑定父组件数据，实现双方通信</li>
<li>子组件向父组件通信，将父组件的事件在子组件中通过 $emit 触发</li>
<li>非父子组件、兄弟组件之间的数据传递<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token comment">/*新建一个Vue实例作为中央事件总嫌*/</span>
<span class="token keyword keyword-let">let</span> event <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Vue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/*监听事件*/</span>
event<span class="token punctuation">.</span><span class="token method function property-access">$on</span><span class="token punctuation">(</span><span class="token string">'eventName'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">val</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">//......do something</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/*触发事件*/</span>
event<span class="token punctuation">.</span><span class="token method function property-access">$emit</span><span class="token punctuation">(</span><span class="token string">'eventName'</span><span class="token punctuation">,</span> <span class="token string">'this is a message.'</span><span class="token punctuation">)</span>
</code></pre></li>
<li>Vuex 数据管理</li>
</ol>
<p><strong>Vue.nextTick 的原理和用途</strong><br>
用途：需要在视图更新之后，基于新的视图进行操作。</p>
<p>Vue 实现响应式并不是数据发生变化之后 DOM 立即变化，而是按一定的策略进行 DOM 的更新。具体来说，异步执行的运行机制如下。</p>
<ol>
<li>
<p>所有同步任务都在主线程上执行，形成一个执行栈（execution context stack）。</p>
</li>
<li>
<p>主线程之外，还存在一个"任务队列"（task queue）。只要异步任务有了运行结果，就在"任务队列"之中放置一个事件。</p>
</li>
<li>
<p>一旦"执行栈"中的所有同步任务执行完毕，系统就会读取"任务队列"，看看里面有哪些事件。那些对应的异步任务，于是结束等待状态，进入执行栈，开始执行。</p>
</li>
<li>
<p>主线程不断重复上面的第三步。</p>
</li>
</ol>
<blockquote>
<p>简单来说，Vue 在修改数据后，视图不会立刻更新，而是等同一事件循环中的所有数据变化完成之后，再统一进行视图更新。</p>
</blockquote>
<p><strong>created、mounted</strong><br>
需要注意的是，在 created 和 mounted 阶段，如果需要操作渲染后的试图，也要使用 nextTick 方法。</p>
<blockquote>
<p>官方文档说明：注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕，可以用 vm.$nextTick 替换掉 mounted</p>
</blockquote>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token function-variable function">mounted</span><span class="token operator">:</span> <span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span><span class="token method function property-access">$nextTick</span><span class="token punctuation">(</span><span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// Code that will run only after the</span>
    <span class="token comment">// entire view has been rendered</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><p><strong>Vue 组件 data 为什么必须是函数</strong></p>
<blockquote>
<p>因为js本身的特性带来的，如果 data 是一个对象，那么由于对象本身属于引用类型，当我们修改其中的一个属性时，会影响到所有Vue实例的数据。如果将 data 作为一个函数返回一个对象，那么每一个实例的 data 属性都是独立的，不会相互影响了</p>
</blockquote>
<p><strong>说一下Vue的双向绑定数据的原理</strong></p>
<blockquote>
<p>vue 实现数据双向绑定主要是：采用数据劫持结合发布者-订阅者模式的方式，通过 Object.defineProperty() 来劫持各个属性的 setter，getter，在数据变动时发布消息给订阅者，触发相应监听回调，通过diff算法，改变虚拟dom，实现页面刷新</p>
</blockquote>
<p><strong>vue数据代理原理Object.defineProperty()</strong><br>
什么是数据代理</p>
<ul>
<li>通过一个对象，代理对另一个对象data中属性的操作（读/写）。目的是为了更方便操作data中的数据</li>
</ul>
<p>语法</p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token known-class-name class-name">Object</span><span class="token punctuation">.</span><span class="token method function property-access">defineProperty</span><span class="token punctuation">(</span>
  obj<span class="token punctuation">,</span> <span class="token comment">//表示被添加（特性）的对象</span>
  prop<span class="token punctuation">,</span> <span class="token comment">// 表示添加的属性</span>
  descriptor <span class="token comment">//表示要定义或修改的属性值</span>
<span class="token punctuation">)</span>
<span class="token comment">// 如下例子</span>
<span class="token keyword keyword-let">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"kubo"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-let">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// 为obj2添加新特性name</span>
<span class="token known-class-name class-name">Object</span><span class="token punctuation">.</span><span class="token method function property-access">defineProperty</span><span class="token punctuation">(</span>obj2<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token comment">// 当obj2的name值被读取时,调用get函数</span>
  <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 返回obj1的数据</span>
    <span class="token keyword control-flow keyword-return">return</span> obj1<span class="token punctuation">.</span><span class="token property-access">name</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token comment">// 当obj2的name值被修改时,调用set函数</span>
  <span class="token function">set</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    obj1<span class="token punctuation">.</span><span class="token property-access">name</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p>数据代理的基本原理</p>
<ul>
<li>通过Object.defineProperty方法，将data对象中所有的属性添加到vm上</li>
<li>为每一个添加到vm上的属性，都配置setter和getter等响应式操作，实现对对象里面属性监视</li>
<li>在setter/getter内部操作data中对应的属性。（ 这样改了属性就会引起对应的setter调用，会重新解析模板）</li>
<li>模板重新解析的时候，会重新生成虚拟Dom,新旧DOM对比，重新渲染页面</li>
</ul>
<p>Vue中数据代理过程</p>
<ul>
<li>实例化vue后，得到实例对象vm。</li>
<li>将options配置项目里的data数据存储一份至vm的_data<br>
(至此，vm自身还没有data里的数据，但是可以通过vm._data获取到)</li>
<li>（开始代理）vm利用Object.defineProperty方法开始为自身添加_data中的属性。属性值是通过getter读取到_data中对应的属性值。</li>
</ul>
<p>数据代理</p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token known-class-name class-name">Object</span><span class="token punctuation">.</span><span class="token method function property-access">defineProperty</span><span class="token punctuation">(</span>vm<span class="token punctuation">,</span><span class="token string">'name'</span><span class="token punctuation">,</span><span class="token punctuation">{</span>
    <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword control-flow keyword-return">return</span> vm<span class="token punctuation">.</span><span class="token property-access">_data</span><span class="token punctuation">.</span><span class="token property-access">name</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token function">set</span><span class="token punctuation">(</span>newval<span class="token punctuation">)</span><span class="token punctuation">{</span>
        vm<span class="token punctuation">.</span><span class="token property-access">_data</span><span class="token punctuation">.</span><span class="token property-access">name</span> <span class="token operator">=</span> newval
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre><p>数据代理的作用</p>
<ol>
<li>
<p>简化代码<br>
假设我们没有数据代理，我们在使用插值语句的时候使用了{{_data.xxxx}}这样就增加了代码量，也非常的不方便<br>
把_data中的属性通过Object.defineProperty方法一条一条的绑定到vm实例上面，访问vm上面的属性就可以直接访问_data中的属性，在差值语法中可以直接{{xxxxx}}</p>
</li>
<li>
<p>实现双向绑定<br>
在Vue中当我们修改了通过defineProperty方法添加到vm实例上面的属性，会触发set函数<br>
set函数做的第一件事就是赋值<br>
set还做了第二件事<br>
作为发布者发出通知：“我是属性 xxx，我变了”。文本节点则是作为订阅者，在收到消息后执行相应的更新操作。 mvvm</p>
</li>
</ol>
<blockquote>
<p>发出通知 dep.notify() =&gt; 触发订阅者的 update 方法 =&gt; 更新视图。</p>
</blockquote>
<p><strong>vue2.0双向数据绑定存在的问题</strong></p>
<ol>
<li>Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对property执行 getter/setter转化，所以property必须在 data对象上存在才能让 Vue 将它转换为响应式的。</li>
<li>当你利用索引直接设置一个数组项时，例如：vm.items[indexOfItem] = newValue<br>
当你修改数组的长度时，例如：vm.items.length = newLength vue是不能检测属性变化的</li>
</ol>
<blockquote>
<p>对于以上两种情况也有解决方案，使用$set方法</p>
</blockquote>
<p><strong>vue3.0中proxy数据双向绑定</strong></p>
<ul>
<li>Proxy 可以直接监听对象而非属性；</li>
<li>Proxy 可以直接监听数组的变化；</li>
<li>Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的；</li>
<li>Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改；</li>
<li>Proxy 作为新标准将受到浏览器厂商重点持续的性能优化，也就是传说中的新标准的性能红利；</li>
</ul>
<p><strong>vue2与vue3的区别是什么</strong></p>
<blockquote>
<p>区别于vue2Object.defineProperty一次性只能给对象的一个属性添加get&amp;set方法，而Proxy一次性给对象所有属性都设置get&amp;set方法</p>
</blockquote>
<p><strong>简单说一下diff算法</strong></p>
<blockquote>
<p>整体的策略就是：深度优先，同层比较</p>
</blockquote>
<ol>
<li>diff算法是虚拟DOM技术的必然产物：通过新旧虚拟DOM作对比(即diff)，将变化的地方更新在真实DOM作上；另外，也需要diff高效的执行对比过程，从而降低时间复杂度为O(n)。</li>
<li>vue2中为了降低Watcher检度，每个组件只有一个Watcher与之对应，只有引入diff才能精确找到发生变化的地方。</li>
<li>vue中diff执行的时刻是组件实例执行其更新函数时，它会比对上一次渲染结果oldVnode和新的渲染结果newVnode，此过程称为patch。</li>
<li>diff过程整体遵循深度优先、同层比较的策略；两个节点之间比较会根据它们是否拥有子节点或者文本节点做不同操作；比较两组子节点是算法的重点，首先假设头尾节点可能相同做4次比对尝试，如果没有找到相同节点才按照通用方式遍历查找，查找结束再按情况处理剩下的节点；借助key通常可以非常精确找到相同节点，因此整个patch过程非常高效。</li>
</ol>
<p><strong>第一次页面加载会触发哪几个钩子？</strong></p>
<blockquote>
<p>beforeCreate， created， beforeMount， mounted</p>
</blockquote>
<p><strong>简述每个周期具体适合哪些场景</strong></p>
<ul>
<li>beforeCreate：在new一个vue实例后，只有一些默认的生命周期钩子和默认事件，其他的东西都还没创建。在beforeCreate生命周期执行的时候，data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法</li>
<li>create：data 和 methods都已经被初始化好了，如果要调用 methods 中的方法，或者操作 data 中的数据，最早可以在这个阶段中操作</li>
<li>beforeMount：执行到这个钩子的时候，在内存中已经编译好了模板了，但是还没有挂载到页面中，此时，页面还是旧的</li>
<li>mounted：执行到这个钩子的时候，就表示Vue实例已经初始化完成了。此时组件脱离了创建阶段，进入到了运行阶段。 如果我们想要通过插件操作页面上的DOM节点，最早可以在和这个阶段中进行</li>
<li>beforeUpdate： 当执行这个钩子时，页面中的显示的数据还是旧的，data中的数据是更新后的， 页面还没有和最新的数据保持同步</li>
<li>updated：页面显示的数据和data中的数据已经保持同步了，都是最新的</li>
<li>beforeDestory：Vue实例从运行阶段进入到了销毁阶段，这个时候上所有的 data 和 methods ， 指令， 过滤器 ……都是处于可用状态。还没有真正被销毁</li>
<li>destroyed： 这个时候上所有的 data 和 methods ， 指令， 过滤器 ……都是处于不可用状态。组件已经被销毁了。</li>
</ul>
<p><strong>说说 vue 内置指令</strong></p>
<ul>
<li>v-once - 定义它的元素或组件只渲染一次，包括元素或组件的所有节点，首次渲染后，不再随数据的变化重新渲染，将被视为静态内容。</li>
<li>v-cloak - 这个指令保持在元素上直到关联实例结束编译 -- 解决初始化慢到页面闪动的最佳实践。</li>
<li>v-bind - 绑定属性，动态更新HTML元素上的属性。例如 v-bind:class。</li>
<li>v-on - 用于监听DOM事件。例如 v-on:click v-on:keyup</li>
<li>v-html - 赋值就是变量的innerHTML -- 注意防止xss攻击</li>
<li>v-text - 更新元素的textContent</li>
<li>v-model - 1、在普通标签。变成value和input的语法糖，并且会处理拼音输入法的问题。2、再组件上。也是处理value和input语法糖。</li>
<li>v-if / v-else / v-else-if。可以配合template使用；在render函数里面就是三元表达式。</li>
<li>v-show - 使用指令来实现 -- 最终会通过display来进行显示隐藏</li>
<li>v-for - 循环指令编译出来的结果是 -L 代表渲染列表。优先级比v-if高最好不要一起使用，尽量使用计算属性去解决。注意增加唯一key值，不要使用index作为key。</li>
<li>v-pre - 跳过这个元素以及子元素的编译过程，以此来加快整个项目的编译速度。</li>
</ul>
<p><strong>v-if 和 v-show 区别</strong></p>
<blockquote>
<p>共同点：都能控制元素的显示和隐藏；<br>
不同点：实现本质方法不同，v-show本质就是通过控制css中的display设置为none，控制隐藏，只会编译一次；v-if是动态的向DOM树内添加或者删除DOM元素，若初始值为false，就不会编译了。而且v-if不停的销毁和创建比较消耗性能。<br>
总结：如果要频繁切换某节点，使用v-show(切换开销比较小，初始开销较大)。如果不需要频繁切换某节点使用v-if（初始渲染开销较小，切换开销比较大）。</p>
</blockquote>
<p><strong>v-for为什么要加key</strong></p>
<blockquote>
<p>如果不使用key，Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。key 是为Vue中Vnode的唯一标识，通过这个key，我们的diff操作可以更准确、更快速。<br>
<strong>更准确</strong>：因为带key就不是就地复用了，在sameNode函数 a.key === b.key 对比中可以避免就地复用的情况。所以更加准确。<br>
<strong>更快速</strong>：利用key的唯一性生成map对象来获取对应节点，比遍历方式块。</p>
</blockquote>
<p><strong>对 keep-alive 的了解</strong></p>
<blockquote>
<p>keep-alive 是 Vue 内置的一个组件，可以使被包含的组件保留状态，或避免重新渲染</p>
</blockquote>
<p><strong>Vue 中怎么自定义指令</strong></p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token comment">/*全局注册*/</span>
<span class="token comment">// 注册一个全局自定义指令 `v-focus`</span>
<span class="token maybe-class-name">Vue</span><span class="token punctuation">.</span><span class="token method function property-access">directive</span><span class="token punctuation">(</span><span class="token string">'focus'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token comment">// 当被绑定的元素插入到 DOM 中时……</span>
  <span class="token function-variable function">inserted</span><span class="token operator">:</span> <span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 聚焦元素</span>
    el<span class="token punctuation">.</span><span class="token method function property-access">focus</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">/*局部注册*/</span>
<span class="token literal-property property">directives</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">focus</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token comment">// 指令的定义</span>
    <span class="token function-variable function">inserted</span><span class="token operator">:</span> <span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      el<span class="token punctuation">.</span><span class="token method function property-access">focus</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p><strong>vue中computed methods区别</strong></p>
<blockquote>
<p>与methods属性相比，computed内部有缓存机制(数据复用)，效率更高，调试更方便，原理：底层借助了Object.defineProperty方法提供的getter和setter</p>
</blockquote>
<p><strong>vue中key什么时候不能用index</strong></p>
<blockquote>
<p>如果不存在对数据的逆序添加、逆序删除等破坏顺序操作，仅用于渲染列表用于展示，使用index作为key是没有问题的。</p>
</blockquote>
<p><strong>Vuex常见面试题</strong></p>
<ol>
<li>Vuex有哪几种属性？
<blockquote>
<p>有五种，分别是 State、 Getter、Mutation 、Action、 Module<br>
state =&gt; 基本数据(数据源存放地)<br>
getters =&gt; 从基本数据派生出来的数据<br>
mutations =&gt; 提交更改数据的方法，同步！<br>
actions =&gt; 像一个装饰器，包裹mutations，使之可以异步。<br>
modules =&gt; 模块化Vuex</p>
</blockquote>
</li>
<li>Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中？
<blockquote>
<p>如果请求来的数据是不是要被其他组件公用，仅仅在请求的组件内使用，就不需要放入vuex 的state里。<br>
如果被其他地方复用，这个很大几率上是需要的，如果需要，请将请求放入action里，方便复用。</p>
</blockquote>
</li>
</ol>
<p><strong>vue-router常见面试题</strong></p>
<ol>
<li>vue-router的两种模式
<blockquote>
<ol>
<li>hash模式：即地址栏 URL 中的 # 符号</li>
<li>history模式：window.history对象打印出来可以看到里边提供的方法和记录长度。利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。（需要特定浏览器支持）</li>
</ol>
</blockquote>
</li>
<li>$route 和 $router的区别
<blockquote>
<ol>
<li>$router 为 VueRouter 实例，想要导航到不同 URL，则使用 $router.push()</li>
<li>$route 为当前 router 跳转对象里面可以获取 name 、 path 、 query 、 params 等</li>
</ol>
</blockquote>
</li>
<li>vue-router 使用params与query传参有什么区别
<blockquote>
<ul>
<li>params 是路由的一部分,必须要有。query 是拼接在 url 后面的参数，没有也没关系</li>
<li>params 不设置的时候，刷新页面或者返回参数会丢，query 则不会有这个问题</li>
</ul>
</blockquote>
</li>
<li>vue-router 有哪几种导航钩子
<blockquote>
<ol>
<li>全局导航钩子：router.beforeEach(to,from,next)，作用：跳转前进行判断拦截。</li>
<li>组件内的钩子 beforeRouteEnter(to,from,next)</li>
<li>单独路由独享组件 beforeEnter(to,from,next)</li>
</ol>
</blockquote>
</li>
</ol>
<hr>
<h2 id="http">HTTP </h2>
<p><strong>http和https区别</strong></p>
<ul>
<li>简述</li>
</ul>
<blockquote>
<p>HTTP协议传输的数据都是未加密的，也就是明文的，因此使用HTTP协议传输隐私信息非常不安全，为了保证这些隐私数据能加密传输，于是网景公司设计了SSL（Secure Sockets Layer）协议用于对HTTP协议传输的数据进行加密，从而就诞生了HTTPS。简单来说，HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议，要比http协议安全。<br>
总的来说： HTTPS=SSL+HTTP</p>
</blockquote>
<ul>
<li>区别</li>
</ul>
<ol>
<li>https协议需要到ca申请证书，一般免费证书较少，因而需要一定费用。</li>
<li>http是超文本传输协议，信息是明文传输，https则是具有安全性的ssl加密传输协议。</li>
<li>http和https使用的是完全不同的连接方式，用的端口也不一样，前者是80，后者是443。（这个只是默认端口不一样，实际上端口是可以改的）</li>
<li>http的连接很简单，是无状态的；HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议，比http协议安全。</li>
</ol>
<p><strong>三次握手过程理解</strong></p>
<blockquote>
<p>第一次握手：建立连接时，客户端发送syn包（syn=x）到服务器，并进入SYN_SENT状态，等待服务器确认；SYN：同步序列编号（Synchronize Sequence Numbers）。<br><br>
第二次握手：服务器收到syn包，必须确认客户的SYN（ack=x+1），同时自己也发送一个SYN包（syn=y），即SYN+ACK包，此时服务器进入SYN_RECV状态；<br><br>
第三次握手：客户端收到服务器的SYN+ACK包，向服务器发送确认包ACK(ack=y+1），此包发送完毕，客户端和服务器进入ESTABLISHED（TCP连接成功）状态，完成三次握手。</p>
</blockquote>
<p><strong>四次挥手</strong></p>
<blockquote>
<p>第一次挥手:客户端A发送一个FIN.用来关闭客户A到服务器B的数据传送 <br><br>
第二次挥手:服务器B收到这个FIN. 它发回一个ACK，确认序号为收到的序号+1。和SYN一样，一个FIN将占用一个序号<br><br>
第三次挥手:服务器B关闭与客户端A的连接，发送一个FIN给客户端A<br><br>
第四次挥手:客户端A发回ACK报文确认，并将确认序号设置为序号加1</p>
</blockquote>
<p><strong>https握手</strong></p>
<ol>
<li>首先客户端发起请求到服务端，服务端处理后发送一个公钥给客户端</li>
<li>客户端进行验证公钥，看公钥是否有效和是否过期</li>
<li>客户端验证通过会产生随机值key，然后用公钥进行加密回传给服务端</li>
<li>服务端用私钥解密后获得客户端的随机值key</li>
<li>利用随机值key加密数据后传输给客户端</li>
<li>客户端利用key值进行解密数据</li>
<li>客户端获取真正的数据</li>
</ol>
<p><strong>请你说说 HTTP1.x 和 HTTP2.0 的区别是什么？/HTTP2.0有哪些优点</strong></p>
<ol>
<li>传输方式：HTTP1.x使用序列化的文本方式进行传输，而HTTP2.0采用二进制格式进行传输。这意味着HTTP2.0传输更为高效，因为文本格式需要在传输前解析成许多文本标记，而二进制格式则节省了大量解析成本。</li>
<li>多路复用：HTTP2.0引入了多路复用的概念，允许多个请求和响应同时进行，而HTTP1.x中只能一个请求和一个响应在同一时间进行。这意味着HTTP2.0可以提高网络资源的利用率并减少延迟。</li>
<li>头压缩：HTTP2.0引入了头压缩机制，通过压缩头部信息来降低带宽占用。而HTTP1.x没有这个特性，每个请求的头部都需要重复发送。</li>
<li>服务器推送：HTTP2.0支持服务器推送，即服务器可以在客户端询问前就将客户端所需要的资源预先推送到客户端。这可以提高客户端的访问速度，而HTTP1.x没有这个功能。</li>
</ol>
<p><strong>HTTP1.x 有哪些问题</strong></p>
<ol>
<li>队头阻塞：如果仅仅使用一个连接，它需要发起请求、等待响应，之后才能发起下一个请求。在请求应答过程中，如果出现任何状况，剩下所有的工作都会被阻塞在那次请求应答之后。这就是“队头阻塞”，它会阻碍网络传输和Web页面渲染，直至失去响应。为了防止这种问题，现代浏览器会针对单个域名开启6个连接，通过各个连接分别发送请求。它实现了某种程度上的并行，但是每个连接仍会受到“队头阻塞”的影响。</li>
<li>低效的TCP利用：HTTP1并不支持多路复用，TCP协议保证连接都能正常工作，但是不能保证它们的性能是最优的。</li>
<li>臃肿的消息首部：虽然h1提供了压缩被请求内容的机制，但是消息首部却无法压缩。</li>
<li>受限的优先级设置浏览器能指定优先级的方式是有限的：要么发起请求，要么不发起。浏览器为了先请求优先级高的资源，会推迟请求其他资源。但是优先级高的资源获取之后，在处理的过程中，浏览器并不会发起新的资源请求，所以服务器无法利用这段时间发送优先级低的资源，总的页面下载时间因此延长了。</li>
<li>第三方资源：很多第三方资源都不在Web开发者的控制范围内，所以很可能其中有些资源的性能很差，会延迟甚至阻塞页面渲染。</li>
</ol>
<p>*<strong>HTTP2.0 有哪些配置</strong><br>
部署分为两步：</p>
<ol>
<li>获取并安装一个支持h2的Web服务器</li>
<li>下载并安装一张TLS证书，让浏览器和服务器通过h2连接。申请TLS证书方法有</li>
</ol>
<p>Nginx支持HTTP2</p>
<ol>
<li>查看当前模块/usr/local/nginx/sbin/nginx -V</li>
</ol>
<blockquote>
<p>configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module</p>
</blockquote>
<ol start="2">
<li>进入nginx源码包目录/home/work/nginx-1.12.0</li>
<li>重新编译，增加httpv2模块。</li>
</ol>
<blockquote>
<p>./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module</p>
</blockquote>
<ol start="4">
<li>make编译，这里不要进行 make install，否则就是覆盖安装。</li>
</ol>
<ul>
<li>新生成的nginx存放位置在nginx源码下的objs下</li>
<li>将原nginx做备份，将新nginx替换老nginx</li>
</ul>
<ol start="5">
<li>新生成的nginx存放位置在nginx源码下的objs下<br>
将原nginx做备份，将新nginx替换老nginx</li>
<li>重启nginx：sudo ./nginx -s reload (如果不生效就kill进程，重启nginx)</li>
</ol>
<p><strong>Content-Type有哪些类型</strong><br>
常见的Content-Type有数百个，下面例举了一些</p>
<ul>
<li>HTML文档标记：text/html;</li>
<li>普通ASCII文档标记：text/html;</li>
<li>JPEG图片标记：image/jpeg;</li>
<li>GIF图片标记：image/gif;</li>
<li>js文档标记：application/javascript;</li>
<li>xml文件标记：application/xml;</li>
<li>等等等等...</li>
</ul>
<p>下面有4种是十分重要</p>
<ol>
<li>application/x-www-form-urlencoded</li>
</ol>
<blockquote>
<p>HTTP会将请求参数用key1=val1&amp;key2=val2的方式进行组织，并放到请求实体里面，注意如果是中文或特殊字符如"/"、","、“:" 等会自动进行URL转码。不支持文件，一般用于表单提交。</p>
</blockquote>
<ol start="2">
<li>multipart/form-data</li>
</ol>
<blockquote>
<p>与application/x-www-form-urlencoded不同，一般用于上传文件他是一个多部分多媒体类型。首先生成了一个 boundary 用于分割不同的字段，在请求实体里每个参数以------boundary开始，然后是附加信息和参数名，然后是空行，最后是参数内容。多个参数将会有多个boundary块。如果参数是文件会有特别的文件域。最后以------boundary–为结束标识。multipart/form-data支持文件上传的格式，一般需要上传文件的表单则用该类型。</p>
</blockquote>
<ol start="3">
<li>application/json</li>
</ol>
<blockquote>
<p>JSON 是一种轻量级的数据格式，以“键-值”对的方式组织的数据。这个使用这个类型，需要参数本身就是json格式的数据，参数会被直接放到请求实体里，不进行任何处理。服务端/客户端会按json格式解析数据（约定好的情况下）。</p>
</blockquote>
<ol start="4">
<li>application/xml 和 text/xml</li>
</ol>
<blockquote>
<p>与application/json类似，这里用的是xml格式的数据，text/xml的话，将忽略xml数据里的编码格式，参考。</p>
</blockquote>
<p>Content-Type的使用</p>
<ol>
<li>
<p>request 的Content-Type/发送请求<br>
一般我们在开发的过程中需要注意客户端发送请求（Request）时的Content-Type设置，特别是使用ajax的时候，如果设置得不准确，很有可能导致请求失败。比如在spring中，如果接口使用了@RequestBody，spring强大的自动解析功能，会将请求实体的内容自动转换为Bean，但前提是请求的Content-Type必须设置为application/json，否正就会返回415错误。</p>
<blockquote>
<p>注：415 错误是 Unsupported media type，即不支持的媒体类型。</p>
</blockquote>
<ol>
<li>如果是一个restful接口（json格式），一般将Content-Type设置为application/json; charset=UTF-8；</li>
<li>如果是文件上传，一般Content-Type设置为multipart/form-data</li>
<li>如果普通表单提交，一般Content-Type设置为application/x-www-form-urlencoded</li>
</ol>
</li>
<li>
<p>response的Content-Type/接受请求<br>
服务端响应（Response）的Content-Type最好也保持准确，虽然一般web开发中，前端解析响应的数据不会根据Content-Type，并且服务端一般能自动设置准确的Content-Type，但是如果乱设置某些情况下可能会有问题，比如导出文件，打开图片等。如果在spring项目里使用@ResponseBody，spring会将响应的Content-Type设置为application/json;charset=UTF-8;，可能会导致文件无法导出，需要注意下。</p>
<ol>
<li>一般情况下不需要显示设置；</li>
<li>如果是文件导出，Content-Type 设置为 multipart/form-data，并且添加一个Content-Disposition设置为attachment;fileName=文件.后缀。</li>
</ol>
<blockquote>
<p>注：Content-Disposition是Content-Type的扩展，告诉浏览器弹窗下载框，而不是直接在浏览器里展示文件。因为一般浏览器对于它能够处理的文件类型，如txt，pdf 等，它都是直接打开展示，而不是弹窗下载框。</p>
</blockquote>
</li>
</ol>
<hr>
<h2 id="算法">算法 </h2>
<p><strong>斐波那契数列</strong></p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token comment">// 1、1、2、3、5、8、13、21、34</span>
<span class="token keyword keyword-function">function</span> <span class="token function">fib</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword keyword-const">const</span> arr <span class="token operator">=</span> <span class="token known-class-name class-name">Array</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">fill</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>num <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">||</span> num <span class="token operator">===</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-else">else</span> <span class="token punctuation">{</span>
    <span class="token keyword keyword-const">const</span> diff <span class="token operator">=</span> num <span class="token operator">-</span> arr<span class="token punctuation">.</span><span class="token property-access">length</span><span class="token punctuation">;</span>
    <span class="token keyword control-flow keyword-for">for</span> <span class="token punctuation">(</span><span class="token keyword keyword-let">let</span> index <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> index <span class="token operator">&lt;</span> diff<span class="token punctuation">;</span> index<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      arr<span class="token punctuation">.</span><span class="token method function property-access">push</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token method function property-access">at</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> arr<span class="token punctuation">.</span><span class="token method function property-access">at</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token keyword control-flow keyword-return">return</span> arr<span class="token punctuation">[</span>num <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token function">fib</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><p><strong>实现一个get方法，取对象指定路径的值</strong></p>
<pre data-role="codeBlock" data-info="javascript" class="language-javascript javascript"><code><span class="token comment">// const object = { a: [{ b: { c: 3 } }] };</span>
<span class="token comment">// get(object, 'a[0].b.c');</span>
<span class="token comment">// 实现一个get方法，取对象指定路径的值。输出3</span>
<span class="token keyword keyword-function">function</span> <span class="token function">get</span><span class="token punctuation">(</span><span class="token parameter">object<span class="token punctuation">,</span> key</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword keyword-const">const</span> keys <span class="token operator">=</span> key<span class="token punctuation">.</span><span class="token method function property-access">split</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword keyword-let">let</span> obj <span class="token operator">=</span> <span class="token known-class-name class-name">JSON</span><span class="token punctuation">.</span><span class="token method function property-access">parse</span><span class="token punctuation">(</span><span class="token known-class-name class-name">JSON</span><span class="token punctuation">.</span><span class="token method function property-access">stringify</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword control-flow keyword-for">for</span> <span class="token punctuation">(</span><span class="token keyword keyword-const">const</span> item <span class="token keyword keyword-of">of</span> keys<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>item<span class="token punctuation">.</span><span class="token method function property-access">includes</span><span class="token punctuation">(</span><span class="token string">"["</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> item<span class="token punctuation">.</span><span class="token method function property-access">includes</span><span class="token punctuation">(</span><span class="token string">"]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword keyword-const">const</span> index <span class="token operator">=</span> item<span class="token punctuation">.</span><span class="token method function property-access">indexOf</span><span class="token punctuation">(</span><span class="token string">"["</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword keyword-const">const</span> arrayIndex <span class="token operator">=</span> key<span class="token punctuation">[</span>index <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
      <span class="token keyword keyword-const">const</span> arrayKeyIndex <span class="token operator">=</span> key<span class="token punctuation">[</span>index <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
      <span class="token keyword keyword-const">const</span> arrayKey <span class="token operator">=</span> object<span class="token punctuation">[</span>arrayKeyIndex<span class="token punctuation">]</span><span class="token punctuation">;</span>
      obj <span class="token operator">=</span> arrayKey<span class="token punctuation">[</span>arrayIndex<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-else">else</span> <span class="token punctuation">{</span>
      obj <span class="token operator">=</span> obj<span class="token punctuation">[</span>item<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token keyword control-flow keyword-return">return</span> obj<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword keyword-const">const</span> object <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token function">get</span><span class="token punctuation">(</span>object<span class="token punctuation">,</span> <span class="token string">"a[0].b.c"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><hr>

      </div>
      
      
    
    
    
    
    
    
  
    </body></html>